package cn.rokhdelar.ams.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.rokhdelar.ams.management.domain.po.LoginUser;
import cn.rokhdelar.ams.management.domain.po.SysLoginLog;
import cn.rokhdelar.ams.management.domain.query.LoginQuery;
import cn.rokhdelar.ams.management.domain.vo.UserVO;
import cn.rokhdelar.ams.management.service.AuthenticationService;
import cn.rokhdelar.ams.management.service.CaptchaService;
import cn.rokhdelar.ams.management.service.JwtService;
import cn.rokhdelar.ams.management.service.SysLoginLogService;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class AuthenticationServiceImpl implements AuthenticationService {
    private final AuthenticationManager authenticationManager;
    private final CaptchaService captchaService;
    private final JwtService jwtService;
    private final SysLoginLogService sysLoginLogService;

    /**
     * 登录服务
     * @param loginQuery 登录信息
     * @return 登录结果
     */
    @Override
    public Map<String, Object> login(LoginQuery loginQuery, HttpServletRequest request) {
        if(StringUtils.isEmpty(loginQuery.getUsername()) || StringUtils.isEmpty(loginQuery.getPassword())) {
            throw new UsernameNotFoundException("无效的用户名和密码。");
        }

//        Map<String, Object> re = captchaService.verifyCaptcha(loginQuery.getCaptchaUUID(), loginQuery.getCaptchaCode());
//        if (re.get("code") != Boolean.TRUE) {
//            return re;
//        }

        Authentication authentication;
        try {
            authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginQuery.getUsername(), loginQuery.getPassword())
            );
        } catch (BadCredentialsException e) {
            saveLoginLog(loginQuery.getUsername(), request, false);
            throw new BadCredentialsException("无效的用户名和密码。");
        }
        assert authentication != null;
        LoginUser loginUser = (LoginUser)authentication.getPrincipal();
        loginUser.setPassword(null);
        HashMap<String, Object> map = jwtService.generateToken(loginUser);
        UserVO userVO = BeanUtil.copyProperties(loginUser, UserVO.class);
        map.put("user", userVO);
        saveLoginLog(loginQuery.getUsername(), request, true);
        return map;
    }

    /**
     * 校验令牌有效性
     * @return Boolean
     */
    @Override
    public Boolean verifyToken(String token) {
        token = token.substring(7);
        return jwtService.isTokenExpired(token);
    }

    /**
     * // 记录登录日志
     * @param username 用户名
     * @param request HTTP 请求对象
     */

    protected void saveLoginLog(String username, HttpServletRequest request, Boolean isSuccess) {
        SysLoginLog sysLoginLog = new SysLoginLog();
        sysLoginLog.setUsername(username);
        sysLoginLog.setIp(request.getRemoteAddr());
        sysLoginLog.setLoginTime(LocalDateTime.now());
        sysLoginLog.setStatus(isSuccess);

        UserAgent parse = UserAgentUtil.parse(request.getHeader("User-Agent"));
        sysLoginLog.setBrowser(parse.getBrowser().getName());
        sysLoginLog.setOs(parse.getOs().getName());
        sysLoginLogService.save(sysLoginLog);
    }
}
